<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Problems, Level 1</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Problems, Level 1' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../services.html">Services</a></li><li><a href="index.html">problems</a></li><li><a href="index.html#2">Chapter 2: Problems</a></li><li><b>Problems, Level 1</b></li></ul></div>
<p class="purpose">To render problem messages either as plain text or HTML, and write them out to files.</p>

<ul class="toc"><li><a href="2-pl1.html#SP1">&#167;1. Buffering</a></li><li><a href="2-pl1.html#SP7">&#167;7. Problems report and index</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Buffering.</b>Only one error text needs to be stored in memory at any one time, so we keep
it in a single text stream:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ProblemBuffer::clear</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">ProblemBuffer::clear</span></span>:<br/>Problems, Level 2 - <a href="2-pl2.html#SP3_1">&#167;3.1</a>, <a href="2-pl2.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::new</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b> Roughly speaking, text for problem messages comes from two possible sources:
fairly short standard texts inside Inform, and quotations (direct or indirect)
from the source text. The latter are inserted by the routines in this section,
and they are the ones we should be wary of, since bizarre input might cause
absurdly long quotations to be made. A quotation involves copying text from
word <span class="extract"><span class="extract-syntax">w1</span></span> to <span class="extract"><span class="extract-syntax">w2</span></span>, so there are two dangers: copying a single very long word,
or copying too many of them. We protect against the first by using the
<span class="extract"><span class="extract-syntax">%&lt;W</span></span> escape, which truncates long literals. We protect against the second
overflow hazard by limiting the amount of text we are prepared to quote from
any sentence in one go:
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">QUOTATION_TOLERANCE_LIMIT</span><span class="plain-syntax"> </span><span class="constant-syntax">100</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ProblemBuffer::copy_text</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">ProblemBuffer::copy_text</span></span>:<br/><a href="2-pl1.html#SP4">&#167;4</a><br/>Problems, Level 2 - <a href="2-pl2.html#SP3_1">&#167;3.1</a>, <a href="2-pl2.html#SP13_1_2">&#167;13.1.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::truncate</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="constant-syntax">QUOTATION_TOLERANCE_LIMIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">"%&lt;W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>Diverting source quotes.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">redirected_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">redirected_to_A</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">redirected_to_B</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ProblemBuffer::redirect_problem_sentence</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">A</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">B</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">redirected_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">from</span><span class="plain-syntax">; </span><span class="identifier-syntax">redirected_to_A</span><span class="plain-syntax"> = </span><span class="identifier-syntax">A</span><span class="plain-syntax">; </span><span class="identifier-syntax">redirected_to_B</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>These three special character codes are used as a temporary measure to
mask out angle brackets and quotation marks which we don't want to interpret as HTML:
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PROTECTED_LT_CHAR</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="character-syntax">'\x01'</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">PROTECTED_GT_CHAR</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="character-syntax">'\x02'</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">PROTECTED_QUOT_CHAR</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="character-syntax">'\x03'</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ProblemBuffer::copy_source_reference</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">ProblemBuffer::copy_source_reference</span></span>:<br/>Problems, Level 2 - <a href="2-pl2.html#SP12">&#167;12</a>, <a href="2-pl2.html#SP13_1_2">&#167;13.1.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) { </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">"&lt;no text&gt;"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">source_file</span><span class="plain-syntax"> *</span><span class="identifier-syntax">referred</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::file_of_origin</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">referred</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">, </span><span class="string-syntax">"%f"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TextFromFiles::get_filename</span><span class="plain-syntax">(</span><span class="identifier-syntax">referred</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">proj</span><span class="plain-syntax"> = </span><span class="identifier-syntax">HTML::get_link_abbreviation_path</span><span class="plain-syntax">();</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">proj</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">, </span><span class="string-syntax">"%p"</span><span class="plain-syntax">, </span><span class="identifier-syntax">proj</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::prefix_eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">, </span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">, </span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">Str::delete_n_characters</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">, </span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">, </span><span class="string-syntax">"(no file)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">"'"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-pl1.html#SP2" class="function-link"><span class="function-syntax">ProblemBuffer::copy_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">paraphrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">file</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">DESCRIBE_SOURCE_FILE_PROBLEMS_CALLBACK</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">paraphrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DESCRIBE_SOURCE_FILE_PROBLEMS_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">paraphrase</span><span class="plain-syntax">, </span><span class="identifier-syntax">referred</span><span class="plain-syntax">, </span><span class="identifier-syntax">file</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">"' %c%S%c%S%c%d%c"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">, </span><span class="identifier-syntax">paraphrase</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">, </span><span class="identifier-syntax">file</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::location</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">).</span><span class="identifier-syntax">line_number</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">redirected_sentence</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">redirected_to_A</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">redirected_to_B</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Wordings::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">redirected_sentence</span><span class="plain-syntax">), </span><span class="identifier-syntax">W</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">" (which asserts that "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-pl1.html#SP4" class="function-link"><span class="function-syntax">ProblemBuffer::copy_source_reference</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">redirected_to_A</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">" is/are "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-pl1.html#SP4" class="function-link"><span class="function-syntax">ProblemBuffer::copy_source_reference</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">redirected_to_B</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">")"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ProblemBuffer::copy_file_reference</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">ProblemBuffer::copy_file_reference</span></span>:<br/>Problems, Level 2 - <a href="2-pl2.html#SP13_1_1">&#167;13.1.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">file_ref</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">line</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">file_ref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">proj</span><span class="plain-syntax"> = </span><span class="identifier-syntax">HTML::get_link_abbreviation_path</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">proj</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">, </span><span class="string-syntax">"%p"</span><span class="plain-syntax">, </span><span class="identifier-syntax">proj</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::prefix_eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">, </span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">, </span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Str::delete_n_characters</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">, </span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">, </span><span class="string-syntax">"(no file)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">paraphrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">file</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">DESCRIBE_SOURCE_FILE_PROBLEMS_CALLBACK</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">paraphrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DESCRIBE_SOURCE_FILE_PROBLEMS_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">paraphrase</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">file</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">" %c%S%c%S%c%d%c"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">, </span><span class="identifier-syntax">paraphrase</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">, </span><span class="identifier-syntax">file</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>Once the error message is fully constructed, we will want to output it
to a file: in fact, by default it will go in three directions, to
<span class="extract"><span class="extract-syntax">stderr</span></span>, to the debugging log and of course to the problems file. The main
thing is to word-wrap it, since it is likely to be a paragraph-sized
chunk of text, not a single line. The unprintable <span class="extract"><span class="extract-syntax">SOURCE_REF_CHAR</span></span> and
<span class="extract"><span class="extract-syntax">FORCE_NEW_PARA_CHAR</span></span> are simply filtered out for plain text output: for
HTML, they are dealt with elsewhere.
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PROBLEM_WORD_WRAP_WIDTH</span><span class="plain-syntax"> </span><span class="constant-syntax">80</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">problem_count_at_last_in</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">text_stream</span><span class="plain-syntax"> </span><span class="identifier-syntax">problems_file_struct</span><span class="plain-syntax">; </span><span class="comment-syntax"> The actual report of Problems file</span>
<span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">problems_file</span><span class="plain-syntax"> = &amp;</span><span class="identifier-syntax">problems_file_struct</span><span class="plain-syntax">; </span><span class="comment-syntax"> As a </span><span class="extract"><span class="extract-syntax">text_stream *</span></span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">problems_file_active</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> Currently in use</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">currently_issuing_a_warning</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>

<span class="plain-syntax">#</span><span class="identifier-syntax">ifndef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROBLEMS_HTML_EMITTER</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">define</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROBLEMS_HTML_EMITTER</span><span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">endif</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ProblemBuffer::output_problem_buffer_to</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">ProblemBuffer::output_problem_buffer_to</span></span>:<br/><a href="2-pl1.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">line_width</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">html_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">sig_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">break_width</span><span class="plain-syntax"> = </span><span class="constant-syntax">PROBLEM_WORD_WRAP_WIDTH</span><span class="plain-syntax">; </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fallback</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">FORMAT_CONSOLE_PROBLEMS_CALLBACK</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">FORMAT_CONSOLE_PROBLEMS_CALLBACK</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">sig_mode</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">break_width</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">fallback</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> == </span><span class="identifier-syntax">problems_file</span><span class="plain-syntax">) </span><span class="identifier-syntax">html_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sig_mode</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">k</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">indentation</span><span class="plain-syntax">; </span><span class="identifier-syntax">k</span><span class="plain-syntax">++) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"  "</span><span class="plain-syntax">); </span><span class="identifier-syntax">line_width</span><span class="plain-syntax">+=2; }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">first</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">second</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">third</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_1" class="named-paragraph-link"><span class="named-paragraph">Extract details of the first source code reference, if there is one</span><span class="named-paragraph-number">5.1</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_2" class="named-paragraph-link"><span class="named-paragraph">In HTML mode, convert drawing-your-attention arrows</span><span class="named-paragraph-number">5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_3" class="named-paragraph-link"><span class="named-paragraph">In SIG mode, convert drawing-your-attention arrows</span><span class="named-paragraph-number">5.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">inchar32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_4" class="named-paragraph-link"><span class="named-paragraph">In plain text mode, remove bold and italic HTML tags</span><span class="named-paragraph-number">5.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_5" class="named-paragraph-link"><span class="named-paragraph">Issue plain text paraphrase of source reference</span><span class="named-paragraph-number">5.5</span></a></span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_6" class="named-paragraph-link"><span class="named-paragraph">Output single character of problem message</span><span class="named-paragraph-number">5.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">first</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">second</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">third</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_1" class="paragraph-anchor"></a><b>&#167;5.1. </b>In "silence is golden" mode, we will need a filename and line number to
report at: we pick this out as the first source reference in the message.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Extract details of the first source code reference, if there is one</span><span class="named-paragraph-number">5.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0, </span><span class="identifier-syntax">f</span><span class="plain-syntax">=0, </span><span class="identifier-syntax">L</span><span class="plain-syntax">=</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">L</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">inchar32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">) </span><span class="identifier-syntax">f</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">f</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">first</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">f</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">second</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">f</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">third</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-pl1.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2" class="paragraph-anchor"></a><b>&#167;5.2. </b>The plain text "may I draw your attention to the following paragraph"
marker,
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">&gt;--&gt; Which looks like this.</span></span>
</p>

<p class="commentary">is converted into a suitable CSS-styled HTML paragraph with hanging
indentation. And similarly for <span class="extract"><span class="extract-syntax">&gt;++&gt;</span></span>, used to mark continuations.
</p>

<p class="commentary">Note that in HTML, this always opens one paragraph tag.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">In HTML mode, convert drawing-your-attention arrows</span><span class="named-paragraph-number">5.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Str::includes_wide_string_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&gt;--&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">problem_count_at_last_in</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">HTML_TAG</span><span class="plain-syntax">(</span><span class="string-syntax">"hr"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">HTML_OPEN_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">, </span><span class="string-syntax">"class=\"hang\""</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">currently_issuing_a_warning</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;b&gt;Warning.&lt;/b&gt; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;b&gt;Problem.&lt;/b&gt; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&gt;++&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">HTML_OPEN_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">, </span><span class="string-syntax">"class=\"in2\""</span><span class="plain-syntax">) </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"  "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&gt;---&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">); </span><span class="identifier-syntax">HTML_TAG</span><span class="plain-syntax">(</span><span class="string-syntax">"hr"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">problem_count_at_last_in</span><span class="plain-syntax"> = </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax">+1;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">5</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&gt;+++&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">HTML_OPEN_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">, </span><span class="string-syntax">"halftightin3\""</span><span class="plain-syntax">) </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"  "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">5</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&gt;++++&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">HTML_OPEN_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">, </span><span class="string-syntax">"class=\"tightin3\""</span><span class="plain-syntax">) </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"  "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">6</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">HTML_OPEN</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-pl1.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_3" class="paragraph-anchor"></a><b>&#167;5.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">In SIG mode, convert drawing-your-attention arrows</span><span class="named-paragraph-number">5.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">sig_mode</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Str::includes_wide_string_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&gt;--&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\033[1m"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">second</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%p%S:%S: "</span><span class="plain-syntax">, </span><span class="identifier-syntax">HTML::get_link_abbreviation_path</span><span class="plain-syntax">(), </span><span class="identifier-syntax">second</span><span class="plain-syntax">, </span><span class="identifier-syntax">third</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fallback</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%f:1: "</span><span class="plain-syntax">, </span><span class="identifier-syntax">fallback</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\033[31m"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"problem: "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\033[0m"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-pl1.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_4" class="paragraph-anchor"></a><b>&#167;5.4. </b>The problem messages are put together (by Level 2 below) in a plain text
way, but with a little formatting included: in particular, they contain
HTML-style <span class="extract"><span class="extract-syntax">&lt;i&gt;</span></span>, <span class="extract"><span class="extract-syntax">&lt;b&gt;</span></span> and <span class="extract"><span class="extract-syntax">&lt;span&gt;</span></span> tags, which the following code strips
out when writing to plain text format.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">In plain text mode, remove bold and italic HTML tags</span><span class="named-paragraph-number">5.4</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">PROTECTED_LT_CHAR</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">) != </span><span class="constant-syntax">PROTECTED_GT_CHAR</span><span class="plain-syntax">)) </span><span class="identifier-syntax">i</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'&lt;'</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">                ((</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;i&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;b&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;img&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;a&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;font&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;i "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;b "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;img "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;a "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;font "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;span "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;/i&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;/b&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;/img&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;/a&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;/span&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&lt;/font&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)))) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">) != </span><span class="character-syntax">'&gt;'</span><span class="plain-syntax">)) </span><span class="identifier-syntax">i</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-pl1.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_5" class="paragraph-anchor"></a><b>&#167;5.5. </b>Okay, so the format for a source reference here is:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">XparaphraseXfilenameXnumberX</span>
</pre>
<p class="commentary">e.g., <span class="extract"><span class="extract-syntax">Xmain textXsource/story.niX102</span></span>, where <span class="extract"><span class="extract-syntax">X</span></span> is the unprintable
<span class="extract"><span class="extract-syntax">SOURCE_REF_CHAR</span></span>. The counter <span class="extract"><span class="extract-syntax">i</span></span> is at the first <span class="extract"><span class="extract-syntax">X</span></span>, and we must now
convert this to something fit for printing to <span class="extract"><span class="extract-syntax">stdout</span></span>, finishing up with <span class="extract"><span class="extract-syntax">i</span></span>
pointing to the last <span class="extract"><span class="extract-syntax">X</span></span>.
</p>

<p class="commentary">We always use the paraphrase, not the filename, on <span class="extract"><span class="extract-syntax">stdout</span></span> because (i) that's
slightly easier to understand for the user, but more importantly (ii) it
makes the output the same on all platforms when only main text and Standard
Rules are referred to, and that simplifies <span class="extract"><span class="extract-syntax">intest</span></span> and the Test Suite quite
a bit, because we don't have to worry about trivial differences between OS X
and Windows caused by the slashes going the wrong way, and so on.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue plain text paraphrase of source reference</span><span class="named-paragraph-number">5.5</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="identifier-syntax">line_width</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, ++</span><span class="identifier-syntax">i</span><span class="plain-syntax">) != </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_6" class="named-paragraph-link"><span class="named-paragraph">Output single character of problem message</span><span class="named-paragraph-number">5.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, ++</span><span class="identifier-syntax">i</span><span class="plain-syntax">) != </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">) ;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", line "</span><span class="plain-syntax">); </span><span class="identifier-syntax">line_width</span><span class="plain-syntax"> += </span><span class="constant-syntax">7</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, ++</span><span class="identifier-syntax">i</span><span class="plain-syntax">) != </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_6" class="named-paragraph-link"><span class="named-paragraph">Output single character of problem message</span><span class="named-paragraph-number">5.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="identifier-syntax">line_width</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-pl1.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6" class="paragraph-anchor"></a><b>&#167;5.6. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Output single character of problem message</span><span class="named-paragraph-number">5.6</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::is_whitespace</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">)) { </span><span class="comment-syntax"> this starts a run of whitespace</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">l</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::is_whitespace</span><span class="plain-syntax">(</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">l</span><span class="plain-syntax">))) </span><span class="identifier-syntax">l</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">l</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> omit any trailing spaces</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">l</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="comment-syntax"> skip to final whitespace character of the run</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">PROBLEMS_HTML_EMITTER</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="character-syntax">' '</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_6_1" class="named-paragraph-link"><span class="named-paragraph">In plain text mode, wrap the line or print a space as necessary</span><span class="named-paragraph-number">5.6.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">line_width</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">PROTECTED_LT_CHAR</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="character-syntax">'&lt;'</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">PROTECTED_GT_CHAR</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="character-syntax">'&gt;'</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">PROTECTED_QUOT_CHAR</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="character-syntax">'"'</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">PROBLEMS_HTML_EMITTER</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> != </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> != </span><span class="identifier-syntax">FORCE_NEW_PARA_CHAR</span><span class="plain-syntax">)) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%c"</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-pl1.html#SP5">&#167;5</a> and <a href="2-pl1.html#SP5_5">&#167;5.5</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_1" class="paragraph-anchor"></a><b>&#167;5.6.1. </b>At this point, <span class="extract"><span class="extract-syntax">l</span></span> is the position of the first non-whitespace character
after the sequence of whitespace.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">In plain text mode, wrap the line or print a space as necessary</span><span class="named-paragraph-number">5.6.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">word_width</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((!</span><span class="identifier-syntax">Characters::is_whitespace</span><span class="plain-syntax">(</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">l</span><span class="plain-syntax">))) &amp;&amp; (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">l</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        &amp;&amp; (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">l</span><span class="plain-syntax">) != </span><span class="identifier-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">l</span><span class="plain-syntax">++, </span><span class="identifier-syntax">word_width</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">line_width</span><span class="plain-syntax"> + </span><span class="identifier-syntax">word_width</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">break_width</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">); </span><span class="identifier-syntax">line_width</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">l</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">l</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">indentation</span><span class="plain-syntax">+1; </span><span class="identifier-syntax">l</span><span class="plain-syntax">++) { </span><span class="identifier-syntax">line_width</span><span class="plain-syntax">+=2; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"  "</span><span class="plain-syntax">); }</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">); </span><span class="identifier-syntax">line_width</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-pl1.html#SP5_6">&#167;5.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>The following allows us to route individual messages to only one output of
our choice.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">redirected_problem_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> Current destination of problem message text</span>
<span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">ProblemBuffer::redirect_problem_stream</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">redirected_problem_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">S</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">S</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ProblemBuffer::output_problem_buffer</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">ProblemBuffer::output_problem_buffer</span></span>:<br/>Problems, Level 2 - <a href="2-pl2.html#SP3_1">&#167;3.1</a>, <a href="2-pl2.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">redirected_problem_text</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><a href="2-pl1.html#SP5" class="function-link"><span class="function-syntax">ProblemBuffer::output_problem_buffer_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">problems_file</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">problems_file</span><span class="plain-syntax">, </span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-pl1.html#SP5" class="function-link"><span class="function-syntax">ProblemBuffer::output_problem_buffer_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">STREAM_FLUSH</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">DL</span><span class="plain-syntax">, </span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-pl1.html#SP5" class="function-link"><span class="function-syntax">ProblemBuffer::output_problem_buffer_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">DL</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">DL</span><span class="plain-syntax">, </span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><a href="2-pl1.html#SP5" class="function-link"><span class="function-syntax">ProblemBuffer::output_problem_buffer_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">redirected_problem_text</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Problems report and index.</b>That gives us enough infrastructure to produce the final report. Note the use
of error redirection to in order to put pseudo-problem messages &mdash; actually
informational &mdash; into the report. In the case where the run was successful and
there we no Problem messages, we have to be careful to reset <span class="extract"><span class="extract-syntax">problem_count</span></span>
&mdash; it will have been increased by the issuing of these pseudo-problems, and we
need it to remain 0 so that <span class="extract"><span class="extract-syntax">main()</span></span> can finally return back to the operating
system without an error code.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">tail_of_report_written</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ProblemBuffer::write_reports</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">ProblemBuffer::write_reports</span></span>:<br/>Problems, Level 3 - <a href="2-pl3.html#SP3">&#167;3</a>, <a href="2-pl3.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">disaster_struck</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tail_of_report_written</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">tail_of_report_written</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">crash_on_all_problems</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">INFORMATIONAL_ADDENDA_PROBLEMS_CALLBACK</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">INFORMATIONAL_ADDENDA_PROBLEMS_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">disaster_struck</span><span class="plain-syntax">, </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problems_file_active</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">END_PROBLEM_FILE_PROBLEMS_CALLBACK</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">END_PROBLEM_FILE_PROBLEMS_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">problems_file</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">        #</span><span class="identifier-syntax">ifndef</span><span class="plain-syntax"> </span><span class="identifier-syntax">END_PROBLEM_FILE_PROBLEMS_CALLBACK</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">HTML::footer</span><span class="plain-syntax">(</span><span class="identifier-syntax">problems_file</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="2-pl0.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-pm.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-pl0.html">pl0</a></li><li class="progresscurrent">pl1</li><li class="progresssection"><a href="2-pl2.html">pl2</a></li><li class="progresssection"><a href="2-pl3.html">pl3</a></li><li class="progressnext"><a href="2-pl2.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

